#ifndef STR_H
#define STR_H

#include <string>
#include <vector>
#include <iostream>
#include <regex>

using namespace std;

class Str {
public:
    static vector<string> split(string str, string separator) {
        //split str by separator
        vector<string> ret;

        int strLen = str.length();
        int separatorLen = separator.length();

        int st = 0;
        for (int i = 0; i < strLen; i++) {
            if (i + separatorLen - 1 < strLen && str.substr(i, separatorLen) == separator) {
                string segment = str.substr(st, i - st);
                if (segment != "") {
                    ret.push_back(segment);
                }
                st = i + separatorLen;
                i += separatorLen - 1;
            }
        }

        string segment = str.substr(st, strLen);
        if (segment != "") {
            ret.push_back(segment);
        }

        return ret;
    }

    static string between(string str, string leftSeparator, string rightSeparator) {
        int s = leftSeparator.length(), t = str.length() - 1 - rightSeparator.length();
        while (s <= t && str.substr(s - leftSeparator.length(), leftSeparator.length()) != leftSeparator)
            s++;
        if (s > t) {
            cout << "Can not find leftSeparator in Str::between" << endl;
            return "";
        }
        while (s <= t && str.substr(t + 1, rightSeparator.length()) != rightSeparator)
            t--;
        if (s > t) {
            cout << "Can not find rightSeparator in Str::between" << endl;
            return "";
        }
        string ret = str.substr(s, t - s + 1);
        return ret;
    }

    static int toNumber(string str) {
        //tranform str to number
        int ret = 0;

        int strLen = str.length();

        for (int i = 0; i < strLen; i++) {
            if ('0' <= str[i] && str[i] <= '9') {
                ret = ret * 10 + (str[i] - '0');
            } else {
                cout << "Attampt to tranform a not number string to number in Str::toNumber" << endl;
                return 0;
            }
        }

        return ret;
    }

    static string toString(int x) {
        if (x == 0) {
            return "0";
        }
        string ret = "";
        while (x > 0) {
            string number = "0";
            number[0] = '0' + x % 10;
            ret = number + ret;
            x /= 10;
        }
        return ret;
    }

    static string removeChar(string str, char ch) {
        //remove chars equal to ch beside
        string ret = "";

        int s = 0, t = str.length() - 1;
        while (str[s] == ch && s <= t) {
            s++;
        }
        while (str[t] == ch && s <= t) {
            t--;
        }
        for (int i = s; i <= t; i++) {
            ret += str[i];
        }

        return ret;
    }

    static string removeLeadingZero(string str) {
        int s = 0;
        while (s < str.length() && str[s] == '0') {
            s++;
        }
        return str.substr(s, str.length() - s);
    }

    static string removeFollowingSpace(string str) {
        int t = str.length() - 1;
        while (t >= 0 && str[t] == ' ') {
            t--;
        }
        return str.substr(0, t + 1);
    }

    static string getFileExtensions(string str) {
        int index = -1;

        for (int i = str.length() - 1; i >= 0; i--) {
            if (str[i] == '.') {
                index = i;
                break;
            }
        }

        if (index == -1) {
            return "";
        }
        return str.substr(index + 1, str.size() - (index + 1));
    }

    static bool match(string reg, string str) {
        int len = reg.size();
        string res = "";
        for (int i = 0; i < len; i++) {
            if (reg[i] == '%' ) {
                res = res + ".*";
            } else if (reg[i] == '_') {
                res = res + ".";
            } else if( reg[i] == '!' ) {
                res = res + "^";
            } else {
                res = res + reg[i];
            }
        }
        regex pattern(res);
        match_results<string::const_iterator> result;
        return regex_match(str, result, pattern);
    }
};

#endif
